package com.mebs.model.service.labor;

import com.mebs.model.service.Service;
import com.mebs.model.*;

import javax.persistence.*;
import java.util.*;

import org.jt.jet.util.JetUtils;
import org.jt.jet.annotation.Field;
import org.jt.jet.annotation.ArgumentType;

/**
 * Created by Sergey Prasolov, sap@jensentechnologies.com Date: Mar 14, 2006, 2:54:23 PM
 */
@Entity()
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "LABOR")
public class Labor extends Service {
    @ManyToOne(optional = false)
    @JoinColumn(name = "WorkerId")
    private Worker worker;

    @ManyToOne(optional = false)
    @JoinColumn(name = "TaskOrderId")
    private TaskOrder taskOrder;

    @Column(name = "Position", nullable = false, length = 250)
    private String position;

    @Column(name = "StartDate", nullable = false)
    private Date startDate;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "LaborId")
    @OrderBy("startDate,stopDate")
    private Set<Vacation> vacations;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "LaborId")
    @OrderBy("date")
    private Set<Medical> medicalHistory;

    @Column(name = "Salary", nullable = true)
    private Double salary;

    @ManyToOne(optional = true)
    @JoinColumn(name = "CurrencyId")
    @Field(type = ArgumentType.INSTANCE)
    private CurrencyName salaryCurrency;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "LaborId")
    @OrderBy("date,value")
    private Set<SalaryIncrease> increases;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "LaborId")
    @OrderBy("date")
    private Set<Misconduct> misconducts;

    @Column(name = "TerminatedDate", nullable = true)
    private Date terminatedDate;

    @Column(name = "TerminatedReason", nullable = true, length = 1024)
    private String terminatedReason;

    @ManyToOne(optional = true)
    @JoinColumn(name = "LaborStatusId")
    @Field(type = ArgumentType.INSTANCE)
    private LaborStatus status;

    public Labor()
    {
    }

    /**
     * ********************** Getters-setters ***********************
     */

    public Worker getWorker()
    {
        return worker;
    }

    public void setWorker(Worker worker)
    {
        this.worker = worker;
    }

    public TaskOrder getTaskOrder()
    {
        return taskOrder;
    }

    public void setTaskOrder(TaskOrder taskOrder)
    {
        this.taskOrder = taskOrder;
    }

    public String getPosition()
    {
        return position;
    }

    public void setPosition(String position)
    {
        this.position = position;
    }

    public Date getStartDate()
    {
        return startDate;
    }

    public void setStartDate(Date startDate)
    {
        this.startDate = startDate;
    }

    public Set<Vacation> getVacations()
    {
        return vacations;
    }

    public void setVacations(Set<Vacation> vacations)
    {
        this.vacations = vacations;
    }

    public Set<Medical> getMedicalHistory()
    {
        return medicalHistory;
    }

    public void setMedicalHistory(Set<Medical> medicalHistory)
    {
        this.medicalHistory = medicalHistory;
    }

    public Double getSalary()
    {
        return salary;
    }

    public void setSalary(Double salary)
    {
        this.salary = salary;
    }

    public CurrencyName getSalaryCurrency()
    {
        return salaryCurrency;
    }

    public void setSalaryCurrency(CurrencyName salaryCurrency)
    {
        this.salaryCurrency = salaryCurrency;
    }

    public Set<SalaryIncrease> getIncreases()
    {
        return increases;
    }

    public void setIncreases(Set<SalaryIncrease> increases)
    {
        this.increases = increases;
    }

    public Set<Misconduct> getMisconducts()
    {
        return misconducts;
    }

    public void setMisconducts(Set<Misconduct> misconducts)
    {
        this.misconducts = misconducts;
    }

    public Date getTerminatedDate()
    {
        return terminatedDate;
    }

    public void setTerminatedDate(Date terminatedDate)
    {
        this.terminatedDate = terminatedDate;
    }

    public String getTerminatedReason()
    {
        return terminatedReason;
    }

    public void setTerminatedReason(String terminatedReason)
    {
        this.terminatedReason = terminatedReason;
    }

    public LaborStatus getStatus()
    {
        return status;
    }

    public void setStatus(LaborStatus status)
    {
        this.status = status;
    }

    @Override
    public String toString()
    {
        return (this.getSequence() != null) ? this.getSequence().toString() : "";
    }

    @Transient
    public Type getRequirementType()
    {
        return Type.LABOR;
    }

    @Transient
    public boolean isDeletable()
    {
        return JetUtils.isEmpty(vacations) &&
            JetUtils.isEmpty(medicalHistory) &&
            JetUtils.isEmpty(increases) &&
            JetUtils.isEmpty(misconducts);
    }

    @Transient
    public String getSequenceNumber()
    {
        Calendar c = new GregorianCalendar();
        c.setTime(getStartDate());
        return String.format("LAB-%s-%05d-%02d%02d%02d",
            getCompany().getTicker() == null ? "XXX" : getCompany().getTicker(),
            getSequence(),
            c.get(Calendar.YEAR) % 100,
            c.get(Calendar.MONTH) + 1,
            c.get(Calendar.DAY_OF_MONTH));
    }
}
